package mylittleinvestigations.CaseInformation;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import mylittleinvestigations.Utils;

public class CaseMetadata
{
    private final String title;
    private final String description;
    private final int majorVersionRequired;
    private final int minorVersionRequired;
    private final int revisionVersionRequired;
    private BufferedImage imageBeforeCompletion;
    private BufferedImage imageBeforeCompletionFullSize;
    private BufferedImage imageAfterCompletion;
    private BufferedImage imageAfterCompletionFullSize;

    public CaseMetadata(String title, String description, int majorVersionRequired, int minorVersionRequired, int revisionVersionRequired, BufferedImage imageBeforeCompletion, BufferedImage imageBeforeCompletionFullSize, BufferedImage imageAfterCompletion, BufferedImage imageAfterCompletionFullSize)
    {
        this.title = title;
        this.description = description;
        this.majorVersionRequired = majorVersionRequired;
        this.minorVersionRequired = minorVersionRequired;
        this.revisionVersionRequired = revisionVersionRequired;
        this.imageBeforeCompletion = imageBeforeCompletion;
        this.imageBeforeCompletionFullSize = imageBeforeCompletionFullSize;
        this.imageAfterCompletion = imageAfterCompletion;
        this.imageAfterCompletionFullSize = imageAfterCompletionFullSize;
    }

    void SaveToXml(CaseXmlWriter writer, String stagingFolderPath, String privateExponent) throws IOException
    {
        writer.StartElement("CaseMetadata");
        
        writer.WriteTextElement("Title", this.title);
        writer.WriteTextElement("Description", this.description);
        
        writer.StartElement("RequiredVersion");
        writer.StartElement("Version");
        writer.WriteIntElement("Major", majorVersionRequired);
        writer.WriteIntElement("Minor", minorVersionRequired);
        writer.WriteIntElement("Revision", revisionVersionRequired);
        writer.EndElement();
        writer.EndElement();
        
        writer.WritePngElement("ImageBeforeCompletion", this.imageBeforeCompletion);
        
        if (this.imageBeforeCompletionFullSize != null)
        {
            writer.WritePngElement("ImageBeforeCompletionFullSize", this.imageBeforeCompletionFullSize);
        }
        
        writer.WritePngElement("ImageAfterCompletion", this.imageAfterCompletion);
        
        if (this.imageAfterCompletionFullSize != null)
        {
            writer.WritePngElement("ImageAfterCompletionFullSize", this.imageAfterCompletionFullSize);
        }
        
        // Let's sign the case file and then save that signature,
        // if we've been given a private exponent with which to do so.
        if (!Utils.isNullOrEmpty(privateExponent))
        {
            String modulus = "23568332026097843589330224341232423824489227725618860714509096199525106220740317569413957190650367349886057276376951603027658474222300018538090882724127806422184385919973062121722991179344505183372523752666554302712122813070863946812173550830454356506133615226034873458142962497061909667034748542366872519001572246306747534032691513595335005177558602926751208654397458873075388398851331968483672593974371591236988537248649056651919444044050631175982858540930336744213602080363401671845205556669413373412866688398634151430976573005566658278720024181234244924513150893829727777179327452060753074929344789195138168478643";
            String publicExponent = "17";
            String hexEncodedSignature = "";
            String line;

            try
            {
                Process process = Runtime.getRuntime().exec(
                    "FileSigner.exe " +
                    "\"" + Paths.get(stagingFolderPath, "case.xml").toAbsolutePath().toString() + "\" " +
                    modulus + " " +
                    publicExponent + " " +
                    privateExponent);
                process.waitFor();

                BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));

                while ((line = input.readLine()) != null)
                {
                    hexEncodedSignature += line;
                }

                input.close();
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
            }
            catch (InterruptedException ex)
            {
                ex.printStackTrace();
            }

            if (!hexEncodedSignature.isEmpty())
            {
                writer.StartElement("Signatures");
                writer.WriteTextElement("CaseFile", hexEncodedSignature);
                writer.EndElement();
            }
        }
        
        writer.EndElement();
        
        writer.Close();
    }

    public CaseMetadata(CaseXmlReader reader)
    {
        reader.StartElement("CaseMetadata");
        
        this.title = reader.ReadTextElement("Title");
        this.description = reader.ReadTextElement("Description");
        this.majorVersionRequired = 0;
        this.minorVersionRequired = 0;
        this.revisionVersionRequired = 0;
        
        reader.EndElement();
    }
    
    private byte HexToNibble(char hex)
    {
        if (hex >= '0' && hex <= '9')
        {
            return (byte)(hex - '0');
        }
        else if (hex >= 'A' && hex <= 'F')
        {
            return (byte)(hex - 'A' + 10);
        }
        else
        {
            throw new IllegalArgumentException("Invalid hex value: " + hex);
        }
    }
}
